package logic

import (
	"context"
	"fmt"
	"io"
	"net/http"

	"goNutpi/internal/svc"
	"goNutpi/internal/types"

	"github.com/tidwall/gjson"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/rest/httpc"
)

type OhpmSearchLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewOhpmSearchLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OhpmSearchLogic {
	return &OhpmSearchLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *OhpmSearchLogic) OhpmSearch(req *types.OhpmSearchReq) (resp *types.OhpmSearchResp, err error) {
	// todo: add your logic here and delete this line
	url := "https://ohpm.openharmony.cn/ohpmweb/registry/oh-package/openapi/v1/search?" +
		fmt.Sprintf("condition=%s&pageNum=%d&pageSize=%d&sortedType=%s&isHomePage=%v",
			req.Condition, req.PageNum, req.PageSize, req.SortedType, req.IsHomePage)

	res, err := httpc.Do(l.ctx, http.MethodGet, url, nil)
	if err != nil {
		l.Errorf("Failed to make HTTP request: %v", err)
		return nil, err
	}
	defer res.Body.Close()

	body, err := io.ReadAll(res.Body)
	if err != nil {
		l.Errorf("Failed to read response body: %v", err)
		return nil, err
	}

	if res.StatusCode != http.StatusOK {
		l.Errorf("Unexpected status code: %d", res.StatusCode)
		return nil, fmt.Errorf("unexpected status code: %d", res.StatusCode)
	}

	// 解析返回的JSON数据
	jsonResult := gjson.ParseBytes(body)

	if jsonResult.Get("code").Int() != 200 {
		l.Errorf("API returned non-200 code: %d", jsonResult.Get("code").Int())
		return nil, fmt.Errorf("API returned non-200 code: %d", jsonResult.Get("code").Int())
	}

	// 构造返回的数据结构
	resp = &types.OhpmSearchResp{
		Code:    int(jsonResult.Get("code").Int()),
		Message: jsonResult.Get("message").String(),
		Body: types.BodyItem{
			Total:    int(jsonResult.Get("body.total").Int()),
			PageNum:  int(jsonResult.Get("body.pageNum").Int()),
			PageSize: int(jsonResult.Get("body.pageSize").Int()),
			Pages:    int(jsonResult.Get("body.pages").Int()),
		},
	}

	// 解析rows数组
	rows := jsonResult.Get("body.rows").Array()
	for _, row := range rows {
		keywords := make([]string, 0)
		row.Get("keywords").ForEach(func(key, value gjson.Result) bool {
			keywords = append(keywords, value.String())
			return true
		})

		resp.Body.Rows = append(resp.Body.Rows, types.Row{
			Name:              row.Get("name").String(),
			Description:       row.Get("description").String(),
			Org:               row.Get("org").String(),
			PackageType:       row.Get("packageType").String(),
			AuthorName:        row.Get("authorName").String(),
			PublisherId:       row.Get("publisherId").String(),
			PublisherName:     row.Get("publisherName").String(),
			AuthorPicUrl:      row.Get("authorPicUrl").String(),
			LatestVersion:     row.Get("latestVersion").String(),
			LatestPublishTime: row.Get("latestPublishTime").Int(),
			License:           row.Get("license").String(),
			Keywords:          keywords,
			Likes:             int(row.Get("likes").Int()),
			Points:            int(row.Get("points").Int()),
			Popularity:        int(row.Get("popularity").Int()),
		})
	}

	return resp, nil
}
